/**
 * 
 */
package bpel.variables;

import java.util.HashMap;

import bpel.BPELProcess;
import bpel.types.BPELComplexType;
import bpel.types.BPELElement;
import bpel.types.BPELMessage;
import bpel.types.BPELPart;
import bpel.types.BPELType;

/**
 * @author Maurice & Topia
 *
 */
public class BPELVariableFactory {

	private static BPELVariableFactory singleton;

	private BPELVariableFactory() {
		// nothing
	}

	public static BPELVariableFactory getInstance() {
		if (singleton == null) {
			singleton = new BPELVariableFactory();
		}

		return singleton;
	}

	public BPELVariable createVariable(String name, BPELType type, BPELProcess process) {

		BPELVariable variable = null;

		if (type instanceof BPELElement) {
			BPELElement element = (BPELElement) type;

			if (element.hasSubtype()) { //Complex type
				BPELComplexType complexType = element.getSubType();

				HashMap<String, BPELVariable> subVars = new HashMap<String, BPELVariable>();

				//Adding all subtypes
				for (String e : complexType.getElements().keySet()) {
					BPELElement subElement = complexType.getElements().get(e);
					subVars.put(e, createVariable(e, subElement, process));
				}

				variable = new BPELComplexVariable(type, name, subVars);
				
			} else { //Standard type
				variable = new BPELStandardVariable(type, name);
			}
		}

		if (type instanceof BPELComplexType) {

			BPELComplexType complexType = (BPELComplexType) type;

			HashMap<String, BPELVariable> subVars = new HashMap<String, BPELVariable>();

			//Adding all subtypes
			for (String e : complexType.getElements().keySet()) {
				BPELElement subElement = complexType.getElements().get(e);
				subVars.put(e, createVariable(e, subElement, process));
			}

			variable = new BPELComplexVariable(type, name, subVars);
		}

		if (type instanceof BPELMessage) {

			BPELMessage msgType = (BPELMessage) type;
			HashMap<String, HashMap<String, BPELVariable>> parts =  new HashMap<String, HashMap<String,BPELVariable>>();
			
			for (String p : msgType.getParts().keySet()) {
				
				HashMap<String, BPELVariable> elements = new HashMap<String, BPELVariable>();
				
				BPELPart part = msgType.getParts().get(p);
				BPELElement element = (BPELElement) process.getType(part.getElement());
				
				elements.put(element.getName(), createVariable(element.getName(), element, process));
				
				parts.put(p, elements);
			}

			variable = new BPELMessageVariable(type, name, parts);
		}

		return variable;
	}
}
